#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include"ctrl.h"

//const attribute
const int NAME_SIZE = 30;//name charArray limit
const int LABEL_SIZE = 100;//label charArray limit
const int PLAN_SIZE = 20;//planArray limit

struct date {
    int year, month, day;
};

struct plan {
    char name [NAME_SIZE];
    char label [LABEL_SIZE];
    D sTime;
    D eTime;
    
    int taskNum;
    T *headTask;
};

struct task {
    char name [NAME_SIZE];
    char label [LABEL_SIZE];
    D sTime;
    D eTime;
    int importance;
    //basic arrtibutes
    
    task * nextTask;
    task * previousTask;
};

time_t timer;
int year;
int month;
int day;

P plans [PLAN_SIZE];
int plansNum = 0;


void instruction(void){
    printf("*** 1 to see time       ***\n");//查看时间
    printf("*** 2 to see today task ***\n");//查看今日代办任务
    printf("*** 3 to check plan     ***\n");//计划编辑
    printf("*** 4 to open file      ***\n");//打开文件
    printf("*** 5 to save file      ***\n");//储存文件
    printf("*** 6 to get help       ***\n");//获得帮助
    printf("*** 0 to end            ***\n");//结束程序
}

void seeTime(void){
    timer = time(NULL);
    struct tm *time = localtime(&timer);
    printf("*** %.4d/%.2d/%.2d\t%d:%d:%d ***\n", time->tm_year + 1900,
           time->tm_mon + 1, time->tm_mday, time->tm_hour,
           time->tm_min, time->tm_sec);
}

void getToday(void){
    timer = time(NULL);
    struct tm *time = localtime(&timer);
    
    year = time->tm_year + 1900;
    month = time->tm_mon + 1;
    day = time->tm_mday;
}

void seeTask(void){
    getToday();
    
    D today;
    today.year = year;
    today.month = month;
    today.day = day;
    
    int empty = 1;
    
    for(int i = 0;i < plansNum;i++){
        T *ptr = plans[i].headTask;
        while(ptr != NULL){
            if(compareDate(ptr->sTime, today) <= 0
               && compareDate(ptr->eTime, today) >= 0){
                printTask(ptr);
                empty = 0;
                
                ptr = ptr->nextTask;
            }
        }
    }
    
    if(empty == 1)
        printf("*** today has no task ***\n");
}

void checkPlan( ){
    planInstruction();
    int command = -1;
    int index = 0;
    while(command != 0){
        scanf("%d",&command);
        
        switch (command) {
            case 1:
                printPlans();
                break;
            case 2:
                printf("please enter index of plan\n");
                scanf("%d",&index);
                editPlan(index);
                break;
            case 3:
                createPlan();
                break;
            case 4:
                deletePlan();
                break;
            case 5:
                planInstruction();
                break;
            default:
                break;
        }
    }
    instruction();
}
void planInstruction( ){
    printf("*** 1 to print plans    ***\n");//打印所有计划
    printf("*** 2 to edit a plan    ***\n");//编辑某个计划
    printf("*** 3 to create a plan  ***\n");//创建新的计划
    printf("*** 4 to delete a plan  ***\n");//删除某个计划
    printf("*** 5 to get help       ***\n");//获得帮助
    printf("*** 0 to back           ***\n");//返回主界面
}

void printPlans( ){
    if(plansNum == 0)
        printf("*** the system has no plan ***\n");
    else{
        for(int i = 0;i < plansNum;i++){
            printPlan(plans[i]);
        }
    }
}

void printPlan(plan p){
    printf("name: %s\n",p.name);
    printf("label: %s\n",p.label);
    printf("startTime: ");
    printDate(p.sTime);
    printf("\nendTime: ");
    printDate(p.eTime);
    printf("\n");
    
    int count = 0;
    T *ptr = p.headTask;
    
    //printf("%p\n", ptr);
    
    while(ptr) {
        printf("task %d\n",count);
            printTask(ptr);
        
        ptr = ptr->nextTask;
        count++;
        //printf("%d",count);
        //TODO
    }
}

void printTask(task *t){
    if(t){
        printf("name: %s\n",t->name);
        printf("label: %s\n",t->label);
        printf("startTime: ");
        printDate(t->sTime);
        printf("\nendTime: ");
        printDate(t->eTime);
        printf("\nimportance: %.1d\n",t->importance);
    }
}

void editPlan(int index){
    if (index<0||index>=plansNum)
    {
        printf("index cross-border\n");
        return;
    }
    ePlanInstruction();
    int command = -1;
    int indexOfTask = 0;
    while (command != 0) {
        scanf("%d",&command);
        
        switch (command) {
            case 1:
                editPlanName(index);
                break;
            case 2:
                editPlanLabel(index);
                break;
            case 3:
                editPlanStartTime(index);
                break;
            case 4:
                editPlanEndTime(index);
                break;
            case 5:
                createTask(&plans[index]);
                break;
            case 6:
                printf("please enter index of Task!\n");
                scanf("%d",&indexOfTask);
                removeTask(&plans[index],indexOfTask    );
                break;
            case 7:
                printf("please enter index of Task!\n");
                scanf("%d",&indexOfTask);
                editTask(index,indexOfTask);
                break;
            case 8:
                ePlanInstruction();
                break;
            default:
                break;
        }
    }
    planInstruction();
}

void createPlan( ){
     if(plansNum == 20)
        printf("*** the number of plans has reached limit ***\n");
    else{
        char tName [NAME_SIZE] = "";
        char tLabel [LABEL_SIZE] = "";
        date tSTime;
        date tETime;
        
        printf("name: ");
        scanf("%29s",tName);
        printf("label: ");
        scanf("%99s",tLabel);
        printf("startTime\nyear:");
        scanf("%d",&tSTime.year);
        printf("month: ");
        scanf("%d",&tSTime.month);
        printf("day: ");
        scanf("%d",&tSTime.day);
        printf("endTime\nyear:");
        scanf("%d",&tETime.year);
        printf("month: ");
        scanf("%d",&tETime.month);
        printf("day: ");
        scanf("%d",&tETime.day);
        
        plan newPlan;
        initPlan(&newPlan);
        strcpy(newPlan.name, tName);
        strcpy(newPlan.label, tLabel);
        copyDate(&newPlan.sTime, tSTime);
        copyDate(&newPlan.eTime, tETime);
        
        copyPlan(&plans[plansNum], newPlan);
        plansNum++;
        
        printf("*** Successful ***\n");
    }
}

void deletePlan( ){
    printf("*** enter the index ***\n");
    int index = 0;
    scanf("%d",&index);
    
    if(index < 0 || index >= plansNum)
        printf("*** invalid index ***\n");
    else{
        plan temps [PLAN_SIZE];
        
        for(int i = 0;i < PLAN_SIZE;i++)
            initPlan(&temps[i]);
        
        int count = 0;
        for(int i = 0;i < plansNum;i++){
            if(i == index)
                continue;
            else{
                copyPlan(&temps[count], plans[i]);
                count++;
            }
        }
        
        plansNum = count + 1;
        plan empty;
        initPlan(&empty);
        for(int i = 0;i < PLAN_SIZE;i++){
            if(i < count)
                copyPlan(&plans[i], temps[i]);
            else
                copyPlan(&plans[i], empty);
        }
        
        plansNum--;
        printf("*** Successful ***\n");
    }
}

void ePlanInstruction(void){
    printf("*** 1 to set name      ***\n");//设置计划名字
    printf("*** 2 to set label     ***\n");//设置计划标签
    printf("*** 3 to set startTime ***\n");//设置计划起始时间
    printf("*** 4 to set endTime   ***\n");//设置计划截止时间
    printf("*** 5 to create task   ***\n");//创建新的任务
    printf("*** 6 to delete task   ***\n");//删除某个任务
    printf("*** 7 to edit task     ***\n");//编辑某个任务
    printf("*** 8 to get help      ***\n");//获得帮助
    printf("*** 0 to back          ***\n");//返回计划界面
}
void editPlanName(int index)
{
    char tName[NAME_SIZE];
    printf("name: ");
    scanf("%29s",tName);
    strcpy((plans+index)->name,tName);
    printf("*** Successful ***\n");
}

void editPlanLabel(int index)
{
    char tLabel[LABEL_SIZE];
    printf("label: ");
    scanf("%s99",tLabel);
    strcpy((plans+index)->label,tLabel);
    printf("*** Successful ***\n");
}
void editPlanStartTime(int index)
{
    date tSTime;
    printf("startTime\nyear:");
    scanf("%d",&tSTime.year);
    printf("month: ");
    scanf("%d",&tSTime.month);
    printf("day: ");
    scanf("%d",&tSTime.day);
    copyDate(&(plans+index)->sTime,tSTime);
     printf("*** Successful ***\n");
}
void editPlanEndTime(int index)
{
    date tETime;
    printf("endTime\nyear:");
    scanf("%d",&tETime.year);
    printf("month: ");
    scanf("%d",&tETime.month);
    printf("day: ");
    scanf("%d",&tETime.day);
    copyDate(&(plans+index)->eTime,tETime);
     printf("*** Successful ***\n");
}
// void editTaskName(int indexOfPlan,int indexOfTask)
// {
//     T *ptr = (plans+indexOfPlan)->headTask;
//     int count = 0;
//     char tName[NAME_SIZE];
//     scanf("%29s",tName);
//     while(ptr != NULL){
//         if(indexOfTask == count){
//             strcpy(ptr->name,tName);
//         }
//         ptr = ptr->nextTask;
//         count++;
//     }
// }

// void editTaskLabel(int indexOfPlan,int indexOfTask)
// {
//     T *ptr = (plans+indexOfPlan)->headTask;
//     int count = 0;
//     char tLabel[LABEL_SIZE];
//     scanf("%99s",tLabel);
//     while(ptr != NULL){
//         if(indexOfTask == count){
//             strcpy(ptr->label,tLabel);
//         }
//         ptr = ptr->nextTask;
//         count++;
//     }
// }

// void editTaskStartTime(int indexOfPlan,int indexOfTask)
// {
//     T *ptr = (plans+indexOfPlan)->headTask;
//     date tSTime;
//     int count = 0;
//     printf("startTime\nyear:");
//     scanf("%d",&tSTime.year);
//     printf("month: ");
//     scanf("%d",&tSTime.month);
//     printf("day: ");
//     scanf("%d",&tSTime.day);
    
//     while(ptr != NULL){
//         if(indexOfTask == count){
//             copyDate(&ptr->sTime,tSTime);
//         }
//         ptr = ptr->nextTask;
//         count++;
//     }
// }

// void editTaskEndTime(int indexOfPlan,int indexOfTask)
// {
//     T *ptr = (plans+indexOfPlan)->headTask;
//     date tETime;
//     int count = 0;
//     printf("startTime\nyear:");
//     scanf("%d",&tETime.year);
//     printf("month: ");
//     scanf("%d",&tETime.month);
//     printf("day: ");
//     scanf("%d",&tETime.day);
    
//     while(ptr != NULL){
//         if(indexOfTask == count){
//             copyDate(&ptr->eTime,tETime);
//         }
//         ptr = ptr->nextTask;
//         count++;
//     }
// }

void createTask(P *p)
{
    char tName[NAME_SIZE] = "";
    char tLabel[LABEL_SIZE] = "";
    date tSTime;
    date tETime;
    int  tImportance;
    
    printf("name: ");
    scanf("%29s", tName);
    printf("label: ");
    scanf("%99s", tLabel);
    printf("startTime\nyear:");
    scanf("%d", &tSTime.year);
    printf("month: ");
    scanf("%d", &tSTime.month);
    printf("day: ");
    scanf("%d", &tSTime.day);
    printf("endTime\nyear:");
    scanf("%d", &tETime.year);
    printf("month: ");
    scanf("%d", &tETime.month);
    printf("day: ");
    scanf("%d", &tETime.day);
    printf("importance:");
    scanf("%d", &tImportance);
    
    task newTask;
    initTask(&newTask);
    //memset(&newTask, 0, sizeof(task));
    strcpy(newTask.name, tName);
    strcpy(newTask.label, tLabel);
    copyDate(&newTask.sTime, tSTime);
    copyDate(&newTask.eTime, tETime);
    newTask.importance = tImportance;
    
    T *temp = (T *)malloc(sizeof(struct task));
    initTask(temp);
    T *ptr = p->headTask;
    
    copyTask(temp, &newTask);
    if(ptr == NULL){
        p->headTask = temp;
    }
    else{
        while(ptr->nextTask)
            ptr = ptr->nextTask;
        
        ptr->nextTask = temp;
        temp->previousTask = ptr;
        p->taskNum++;
    }
    
    printf("*** Successful ***\n");
}

int removeTask(P *p, int index){
    T *ptr = p->headTask;
    
    if(index < 0 || index > p->taskNum)
        return 0;
    
    if(index == 0){
        p->headTask = ptr->nextTask;
        free(ptr);
        
        printf("*** Successful ***\n");
        return 1;
    }else
    {
        int count = 0;
        while(ptr != NULL){
            if(ptr->nextTask == NULL){
                ptr->previousTask->nextTask = NULL;
                free(ptr);
                
                printf("*** Successful ***\n");
                return 1;
            }
            if(index == count){
                
                ptr->nextTask->previousTask = ptr->previousTask;
                ptr->previousTask->nextTask = ptr->nextTask;
                
                //printf("T1: %s\nT2: %s\nTX: %s\n", ptr->previousTask->name, ptr->nextTask->name, ptr->previousTask->nextTask->name);
                
                free(ptr);
                
                printf("*** Successful ***\n");
                return 1;
            }
            
            ptr = ptr->nextTask;
            count++;
        }
    }
    
    return 0;
}

void editTask(int indexOfPlan,int indexOfTask)
{
    if (indexOfTask<0||indexOfTask>(plans+indexOfPlan)->taskNum)
    {
        printf("*** invalid index ***\n");
        return;
    }
    
    eTaskInstruction();
    int command = -1;
    while (command != 0) {
        scanf("%d",&command);
        
        switch (command) {
            case 1:
                editTaskName(indexOfPlan,indexOfTask);
                break;
            case 2:
                editTaskLabel(indexOfPlan, indexOfTask);
                break;
            case 3:
                editTaskStartTime(indexOfPlan,indexOfTask);
                break;
            case 4:
                editTaskEndTime(indexOfPlan,indexOfTask);
                break;
            case 5:
                setTaskImportance(&plans[indexOfPlan],indexOfTask);
                break;
            case 6:
                printTask(getTask(indexOfPlan,indexOfTask));
                break;
            case 7:
                eTaskInstruction();
                break;
            default:
                break;
        }
    }
    
    ePlanInstruction();
}
void eTaskInstruction( ){
    printf("*** 1 to set name       ***\n");//设置任务名字
    printf("*** 2 to set label      ***\n");//设置任务标签
    printf("*** 3 to set stratTime  ***\n");//设置任务起始时间
    printf("*** 4 to set endTime    ***\n");//设置任务截止时间
    printf("*** 5 to set importance ***\n");//设置任务重要性
    printf("*** 6 to print task     ***\n");//打印任务信息
    printf("*** 7 to get help       ***\n");//获得帮助
    printf("*** 0 to back           ***\n");//返回
}

void editTaskName(int indexOfPlan,int indexOfTask){
    T *ptr = (plans+indexOfPlan)->headTask;
    int count = 0;
    char tName[NAME_SIZE];
    printf("*** name ***\n");
    scanf("%29s",tName);
    while(ptr != NULL){
        if(indexOfTask == count){
            strcpy(ptr->name,tName);
         }
        ptr = ptr->nextTask;
        count++;
    }
    printf("*** Successful ***\n");
}

void editTaskLabel(int indexOfPlan,int indexOfTask){
    T *ptr = (plans+indexOfPlan)->headTask;
    int count = 0;
    char tLabel[LABEL_SIZE];
    printf("*** label ***\n");
    scanf("%99s",tLabel);
    while(ptr != NULL){
        if(indexOfTask == count){
            strcpy(ptr->label,tLabel);
         }
        ptr = ptr->nextTask;
        count++;
    }
    printf("*** Successful ***\n");
}

void editTaskStartTime(int indexOfPlan,int indexOfTask){
    T *ptr = (plans+indexOfPlan)->headTask;
    date tSTime;
    int count = 0;
    printf("startTime\nyear:");
    scanf("%d",&tSTime.year);
    printf("month: ");
    scanf("%d",&tSTime.month);
    printf("day: ");
    scanf("%d",&tSTime.day);
    
     while(ptr != NULL){
        if(indexOfTask == count){
            copyDate(&ptr->sTime,tSTime);
         }
        ptr = ptr->nextTask;
        count++;
    }
    printf("*** Successful ***\n");
}

void editTaskEndTime(int indexOfPlan,int indexOfTask){
    T *ptr = (plans+indexOfPlan)->headTask;
    date tETime;
    int count = 0;
    printf("endTime\nyear:");
    scanf("%d",&tETime.year);
    printf("month: ");
    scanf("%d",&tETime.month);
    printf("day: ");
    scanf("%d",&tETime.day);
    
     while(ptr != NULL){
        if(indexOfTask == count){
            copyDate(&ptr->eTime,tETime);
         }
        ptr = ptr->nextTask;
        count++;
    }
    printf("*** Successful ***\n");
}

//void editTaskImportance(int indexOfPlan,int indexOfTask){
//
//}

int setTaskImportance(P *p,int index){
    if(index < 0 || index >= p->taskNum)
        return 0;
    
    T *ptr = p->headTask;
    for(int i = 0;i < index;i++)
        ptr = ptr->nextTask;
    
    printf("*** enter the importance ***\n");
    int imp = 1;
    scanf("%d",&imp);
    
    if(imp < 1 || imp > 3){
        printf("*** invalid importance ***\n");
        return 0;
    }
    else
        ptr->importance = imp;
    
    printf("*** Successful ***\n");
    return 1;
}

int compareDate(D d1, D d2){
     if(d1.year > d2.year)
        return 1;
    else if(d1.year == d2.year){
        if(d1.month > d2.month)
            return 1;
        else if(d1.month == d2.month){
            if(d1.day > d2.day)
                return 1;
            else if(d1.day == d2.day)
                return 0;
            else
                return -1;
        }
        else
            return -1;
    }
    else
        return -1;
}

void printDate(date d){
    printf("%4d/%.2d/%.2d",d.year,d.month,d.day);
}

void copyDate(date *dst, date src){
    dst->year = src.year;
    dst->month = src.month;
    dst->day = src.day;
}

void copyTask(T *dst, T *src){
    strcpy(dst->name, src->name);
    strcpy(dst->label, src->label);
    copyDate(&dst->sTime, src->sTime);
    copyDate(&dst->eTime, src->eTime);
    dst->importance = src->importance;
    dst->nextTask = src->nextTask;
    dst->previousTask = src->previousTask;
}

void addTask(plan *p, task *t){
    T *temp = (T *)malloc(sizeof(struct task));
    initTask(temp);
    T *ptr = p->headTask;
    
    copyTask(temp, t);
    if(ptr == NULL){
        p->headTask = temp;
    }
    else{
        while(ptr->nextTask)
            ptr = ptr->nextTask;
        
        ptr->nextTask = temp;
        temp->previousTask = ptr;
        p->taskNum++;
    }
}
void copyPlan(plan *dst, plan src){
    strcpy(dst->name, src.name);
    strcpy(dst->label, src.label);
    copyDate(&dst->sTime, src.sTime);
    copyDate(&dst->eTime, src.eTime);
    
    dst->headTask = src.headTask;
    
//    T *ptr = dst->headTask;
//    while(ptr != NULL){
//        ptr = ptr->nextTask;
//
//        removeTask(dst, 0);
//    }
//
//    ptr = dst->headTask;
//    T *srcPtr = src.headTask;
//    while(srcPtr != NULL){
//        ptr = (T*)malloc(sizeof(struct task));
//        initTask(ptr);
//        copyTask(ptr, srcPtr);
//
//        srcPtr = srcPtr->nextTask;
//    }
//
//    dst->taskNum = src.taskNum;
}
T* getTask(int indexOfPlan,int indexOfTask){
    T *t = (plans+indexOfPlan)->headTask;
    int count = 0;
            
    while(t != NULL){
        if(indexOfTask == count){
            return t;
        }
            t = t->nextTask;
            count++;
    }
    
    return NULL;
}

void initDate(date *d){
    d->year = 0;
    d->month = 0;
    d->day = 0;
}

void initTask(task *t){
    strcpy(t->name, "");
    strcpy(t->label, "");
    initDate(&t->sTime);
    initDate(&t->eTime);
    t->importance = 1;
    
    t->previousTask = NULL;
    t->nextTask = NULL;
}

void initPlan(plan *p){
    strcpy(p->name, "");
    strcpy(p->label, "");
    initDate(&p->sTime);
    initDate(&p->eTime);
    p->taskNum = 0;
    
    p->headTask = NULL;
}

void initial( ){
    for(int i = 0;i < PLAN_SIZE;i++)
        initPlan(&plans[i]);
}

int checkHead(char buff[255]){
    char head[9] = "06hkllxx";

    for(int i = 0;i < 8;i++){
        if(buff[i] != head [i])
            return 0;
    }

    return 1;
}

void ctrlOpen(){
    printf("*** enter the file name ***\n");
    
    char fName[100];
    scanf("%99s",fName);
    
    FILE *fp = NULL;
    fp = fopen(fName, "r");
    
    if(!fp){
        printf("*** file %s dose not exist ***\n", fName);
        return;
    }
    else{
        initial();
        char buff[255];
        fgets(buff, 255, (FILE*)fp);
        if(checkHead(buff) == 1){
           
            int planSize = 0;
            fscanf(fp, "%d", &planSize);
            plansNum = planSize;
            
            for(int i = 0;i < planSize;i++){
                fscanf(fp, "%s", plans[i].name);
                fscanf(fp, "%s", plans[i].label);
                fscanf(fp, "%d", &plans[i].sTime.year);
                fscanf(fp, "%d", &plans[i].sTime.month);
                fscanf(fp, "%d", &plans[i].sTime.day);
                fscanf(fp, "%d", &plans[i].eTime.year);
                fscanf(fp, "%d", &plans[i].eTime.month);
                fscanf(fp, "%d", &plans[i].eTime.day);
                
                
                int taskSize = 0;
                fscanf(fp, "%d", &taskSize);
                
                for(int j = 0;j < taskSize;j++){
                    task temp;
                    initTask(&temp);
                    
                    fscanf(fp, "%s", temp.name);
                    fscanf(fp, "%s", temp.label);
                    fscanf(fp, "%d", &temp.sTime.year);
                    fscanf(fp, "%d", &temp.sTime.month);
                    fscanf(fp, "%d", &temp.sTime.day);
                    fscanf(fp, "%d", &temp.eTime.year);
                    fscanf(fp, "%d", &temp.eTime.month);
                    fscanf(fp, "%d", &temp.eTime.day);
                    fscanf(fp, "%d", &temp.importance);
                    
                    addTask(&plans[i], &temp);
                }
            }
        }
        else{
            printf("*** invalid file ***\n");
            return;
        }
    }
    fclose(fp);
    printf("*** Successful ***\n");
}

void ctrlSave(){
    FILE *fp = fopen("ctrl.txt", "w");
    if(!fp){
         printf("open file error.\n");
         return;
    }

    plan p;
    task * temp;
    fprintf(fp, "%s\n", "06hkllxx");
    fprintf(fp, "%d\n", plansNum);
    for(int i = 0; i < plansNum; i++){
        p = plans[i];
        temp = p.headTask;
        fprintf(fp, "%s\n", p.name);
        fprintf(fp, "%s\n", p.label);
        fprintf(fp, "%d ", p.sTime.year);
        fprintf(fp, "%d ", p.sTime.month);
        fprintf(fp, "%d\n", p.sTime.day);
        fprintf(fp, "%d ", p.eTime.year);
        fprintf(fp, "%d ", p.eTime.month);
        fprintf(fp, "%d\n", p.eTime.day);
        if(temp)
            fprintf(fp, "%d\n",p.taskNum + 1);
        while(temp){
            fprintf(fp, "%s\n", temp->name);
            fprintf(fp, "%s\n", temp->label);
            fprintf(fp, "%d ", temp->sTime.year);
            fprintf(fp, "%d ", temp->sTime.month);
            fprintf(fp, "%d\n", temp->sTime.day);
            fprintf(fp, "%d ", temp->eTime.year);
            fprintf(fp, "%d ", temp->eTime.month);
            fprintf(fp, "%d\n", temp->eTime.day);
            fprintf(fp, "%d\n", temp->importance);
            temp = temp->nextTask;
        }
    }
    fprintf(fp, "%s\n", "xxllkh60");
    fclose(fp);
    printf("*** Successful ***\n");
}
